﻿/*
消息格式为2进制
简单类型(符号/无符号的1,2,4字节整数,float,double)就是他们在内存中的格式,没有字节对齐
string/wstring类型: 先4字节表示字符串长度(字符数),不包含尾空,后跟实际字符串,实际字符串也不包含尾空
vector/list/deque/set类型: 先4字节表示容器内元素个数,后跟实际容器内对象
map类型：先4字节表示容器内元素个数,后跟实际容器内对象,以key/value/key/value顺序排列
注意容器的嵌套,例如：map<int,map<int,string>>
Sn方法在数据长度超过MSG_MAX_BUFF_SIZE会抛出异常: _T("msg buffer overflow")
Usn方法在处理消息时,如果长度不够,会抛出异常: _T("not enough buffer")
Usn方法在处理map/set时,如果出现重复的key,会抛出异常: _T("duplicated key")
*/
#pragma once

#define USE_ZLIB
/************************************************************************/
/* 老代码里兼容，用的Buffer是Msg父类的，所以无需自己开内存
   所以，必须在使用MsgSn时，要调用SetBuf方法							*/
/************************************************************************/
//#define COMPATIBLE_OLD_CODE

#include <string>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <tchar.h>
#include <windows.h>
using namespace std;

class MsgOverFlowError : public std::overflow_error
{
public:
	explicit MsgOverFlowError() : std::overflow_error("msg buffer overflow"){}
};

class MsgUnderFlowError : public std::underflow_error
{
public:
	explicit MsgUnderFlowError() : std::underflow_error("not enough buffer"){}
};

class MsgDuplicateKeyError : public std::logic_error
{
public:
	explicit MsgDuplicateKeyError() : std::logic_error("not enough buffer"){}
};
static const size_t MSG_MAX_BUFF_SIZE = 4096;
#define CHECKLEN if(m_len+sizeof(val)>MSG_MAX_BUFF_SIZE) throw MsgOverFlowError();
#define CHECKSHORT if(m_len+sizeof(val)>m_bufflen) throw MsgUnderFlowError();



class MsgSn
{
public:
	MsgSn() {Clear();}
	~MsgSn() {Clear();}

	void Clear() {m_len=0;}

	void SetBuf(char* buff) { /*assert(!"MsgSn-SetBuf-wrong!");*/}

	const char* GetBuf() const {return m_buff;}

	size_t GetLen() const {return m_len;}

	void Compress();


	MsgSn& operator << (char val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (short val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (int val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (long val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (unsigned char val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (unsigned short val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (unsigned int val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (unsigned long val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (float val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (double val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (__int64 val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (unsigned __int64 val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgSn& operator << (bool val) {CHECKLEN memcpy(m_buff+m_len, &val, sizeof(val)); m_len+=sizeof(val); return *this;}

	MsgSn& operator << (const std::string& val)
	{
		size_t vallen = val.length();
		if(m_len + sizeof(size_t) + vallen > MSG_MAX_BUFF_SIZE)
			throw MsgOverFlowError();
		memcpy(m_buff+m_len, &vallen, sizeof(size_t));
		m_len += sizeof(size_t);
		memcpy(m_buff+m_len, val.c_str(), vallen);
		m_len += vallen;
		return *this;
	}

	MsgSn& operator << (const std::wstring& val)
	{
		size_t vallen = val.length();
		if(m_len + sizeof(size_t) + vallen*2 > MSG_MAX_BUFF_SIZE)
			throw MsgOverFlowError();
		memcpy(m_buff+m_len, &vallen, sizeof(size_t));
		m_len += sizeof(size_t);
		vallen *= 2;
		memcpy(m_buff+m_len, val.c_str(), vallen);
		m_len += vallen;
		return *this;
	}

	template<typename T>
	MsgSn& operator << (const std::vector<T>& val)
	{
		size_t vallen = val.size();
		*this << vallen;
		std::vector<T>::const_iterator itend = val.end();
		for(std::vector<T>::const_iterator it=val.begin();it!=itend;++it)
		{
			*this << *it;
		}
		return *this;
	}

	//针对vector<char>特化
	template<>
	MsgSn& operator << (const std::vector<char>& val)
	{
		size_t vallen = val.size();
		*this << vallen;
		if(vallen > 0)
		{
			memcpy(m_buff+m_len, &val[0], vallen);
			m_len += vallen;
		}
		return *this;
	}

	template<typename T>
	MsgSn& operator << (const std::list<T>& val)
	{
		size_t vallen = val.size();
		*this << vallen;
		std::list<T>::const_iterator itend = val.end();
		for(std::list<T>::const_iterator it=val.begin();it!=itend;++it)
		{
			*this << *it;
		}
		return *this;
	}

	template<typename T>
	MsgSn& operator << (const std::deque<T>& val)
	{
		size_t vallen = val.size();
		*this << vallen;
		std::deque<T>::const_iterator itend = val.end();
		for(std::deque<T>::const_iterator it=val.begin();it!=itend;++it)
		{
			*this << *it;
		}
		return *this;
	}

	template<typename T>
	MsgSn& operator << (const std::set<T>& val)
	{
		size_t vallen = val.size();
		*this << vallen;
		std::set<T>::const_iterator itend = val.end();
		for(std::set<T>::const_iterator it=val.begin();it!=itend;++it)
		{
			*this << *it;
		}
		return *this;
	}

	template<typename Tkey, typename Tval>
	MsgSn& operator << (const std::map<Tkey, Tval>& val)
	{
		size_t vallen = val.size();
		*this << vallen;
		std::map<Tkey, Tval>::const_iterator itend = val.end();
		for(std::map<Tkey, Tval>::const_iterator it=val.begin();it!=itend;++it)
		{
			*this << it->first << it->second;
		}
		return *this;
	}

	template<typename T1, typename T2>
	MsgSn& operator << (const std::pair<T1, T2>& val)
	{
		*this << val.first << val.second;
		return *this;
	}

	template<typename T>
	MsgSn& operator << (const T& t) {return t.Sn(*this);}
	void CalcLen() {*(unsigned short*)m_buff=(unsigned short)m_len;}

private:

	char m_buff[MSG_MAX_BUFF_SIZE];

	size_t m_len;
};

class MsgUsn
{
public:
	MsgUsn() {Clear();}
	~MsgUsn() {Clear();}


	void Clear() {m_len=0;  m_bufflen=0;}

	void SetBuf(const char* buf, size_t len) {if(len>MSG_MAX_BUFF_SIZE) throw MsgOverFlowError(); memcpy(m_buff, buf, len); m_len = 0; m_bufflen = len;}

	void ResetLen() {m_len=0;}

	void Uncompress();


	MsgUsn& operator >> (char& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (short& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (int& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (long& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (unsigned char& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (unsigned short& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (unsigned int& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (unsigned long& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (float& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (double& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (__int64& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (unsigned __int64& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}
	MsgUsn& operator >> (bool& val) {CHECKSHORT memcpy(&val, m_buff+m_len, sizeof(val)); m_len+=sizeof(val); return *this;}

	MsgUsn& operator >> (std::string& val)
	{
		size_t vallen;
		*this >> vallen;
		if(m_len + vallen > m_bufflen)
			throw MsgUnderFlowError();
		val.clear();
		val.append(m_buff+m_len, vallen);
		m_len += vallen;
		return *this;
	}

	MsgUsn& operator >> (std::wstring& val)
	{
		size_t vallen;
		*this >> vallen;
		if(m_len + vallen*2 > m_bufflen)
			throw MsgUnderFlowError();
		val.clear();
		val.append((wchar_t*)(m_buff+m_len), vallen);
		m_len += vallen*2;
		return *this;
	}

	template<typename T>
	MsgUsn& operator >> (std::vector<T>& val)
	{
		size_t vallen;
		*this >> vallen;
		if ( vallen > MSG_MAX_BUFF_SIZE)
			throw MsgUnderFlowError();

		val.clear();
		T temp;
		for(size_t i=0;i<vallen;++i)
		{
			*this >> temp;
			val.push_back(temp);
		}
		return *this;
	}

	//针对vector<char>特化
	template<>
	MsgUsn& operator >> (std::vector<char>& val)
	{
		size_t vallen;
		*this >> vallen;
		if(m_len + vallen > m_bufflen)
			throw MsgUnderFlowError();
		val.resize(vallen);
		if(vallen > 0)
		{
			memcpy(&val[0], m_buff+m_len, vallen);
			m_len += vallen;
		}
		return *this;
	}

	template<typename T>
	MsgUsn& operator >> (std::list<T>& val)
	{
		size_t vallen;
		*this >> vallen;
		val.clear();
		T temp;
		for(size_t i=0;i<vallen;++i)
		{
			*this >> temp;
			val.push_back(temp);
		}
		return *this;
	}

	template<typename T>
	MsgUsn& operator >> (std::deque<T>& val)
	{
		size_t vallen;
		*this >> vallen;
		val.clear();
		T temp;
		for(size_t i=0;i<vallen;++i)
		{
			*this >> temp;
			val.push_back(temp);
		}
		return *this;
	}

	template<typename T>
	MsgUsn& operator >> (std::set<T>& val)
	{
		size_t vallen;
		*this >> vallen;
		val.clear();
		T temp;
		for(size_t i=0;i<vallen;++i)
		{
			*this >> temp;
			if(!(val.insert(temp).second))
				throw MsgDuplicateKeyError();
		}
		return *this;
	}

	template<typename Tkey, typename Tval>
	MsgUsn& operator >> (std::map<Tkey, Tval>& val)
	{
		size_t vallen;
		*this >> vallen;
		val.clear();
		Tkey temp1;
		Tval temp2;
		for(size_t i=0;i<vallen;++i)
		{
			*this >> temp1;
			*this >> temp2;
			if(!(val.insert(std::map<Tkey, Tval>::value_type(temp1, temp2)).second))
				throw MsgDuplicateKeyError();
		}
		return *this;
	}

	template<typename T1, typename T2>
	MsgUsn& operator >> (std::pair<T1, T2>& val)
	{
		*this >> val.first >> val.second;
		return *this;
	}

	template<typename T>
	MsgUsn& operator >> (T& t) {return t.Usn(*this);}

private:
	char m_buff[MSG_MAX_BUFF_SIZE];

	size_t m_len;
	size_t m_bufflen;
};
